package com.aqielife.demo.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.logout.RedirectServerLogoutSuccessHandler;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;

import javax.annotation.Resource;
import java.net.URI;

/**
 * @author aqie
 * @date 2022/02/05 12:54
 * @desc
 */
@Slf4j
@EnableWebFluxSecurity
public class WebFluxSecurityConfig  {
  @Resource
  private RedisConnectionFactory redisConnectionFactory;

  @Bean
  public RedisTokenStore redisTokenStore () {
    RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
    redisTokenStore.setPrefix("TOKEN");
    return redisTokenStore;
  }


  @Lazy
  @Autowired
  PasswordEncoder passwordEncoder;

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

  @Bean
  public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    log.info("WebFlux Security begin");
    return http
    .authorizeExchange()
    .pathMatchers("/admin/**")
    .authenticated()
    .pathMatchers("/**")
    .permitAll()
    .and()
    .csrf().disable()

    //.csrfTokenRepository(customCsrfTokenRepository)
    //.requireCsrfProtectionMatcher(customCsrfMatcher)
    .formLogin()
    //.loginPage("/login")
    //.authenticationFailureHandler(new RedirectServerAuthenticationFailureHandler("/login?error"))
    //.authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/admin"))
    .and()
    .logout()
    //.logoutUrl("/logout")
    .logoutSuccessHandler(logoutSuccessHandler("/login?logout"))
    .and()
    .build();
  }

  public ServerLogoutSuccessHandler logoutSuccessHandler(String uri) {
    RedirectServerLogoutSuccessHandler successHandler = new RedirectServerLogoutSuccessHandler();
    successHandler.setLogoutSuccessUrl(URI.create(uri));
    return successHandler;
  }


}
